#pragma once

#include "fxcc/core/graph/directX11/pch.h"

namespace fxcc
{
    namespace graph
    {
        namespace directX11
        {
            struct FXCC_API VertexTypeDesc
            {
                std::string m_Name;
                unsigned int m_VertexStride;
                std::vector<D3D11_INPUT_ELEMENT_DESC > m_InputLayouts;
            };
            struct FXCC_API IndexTypeDesc
            {
                std::string m_Name;
                int m_IndexStride;
                DXGI_FORMAT m_dxgiFormat;
            };
            struct FXCC_API ModeTypeDesc
            {
                std::string m_Name;
                D3D11_PRIMITIVE_TOPOLOGY m_Topology;
            };
            struct FXCC_API DataTypeDesc
            {

            };

            struct FXCC_API SamplerTypeDesc
            {
                std::string m_Name;
                ComPtr<ID3D11SamplerState> m_SamplerState;

            };

            struct FXCC_API FormatDesc
            {
                DXGI_FORMAT m_Format;
                DXGI_FORMAT m_hdrFormat;

            };
            struct FXCC_API SamplerDesc
            {

            };
            struct FXCC_API DepthStencilDesc
            {

            };
            struct FXCC_API BlendDesc
            {

            };
            struct FXCC_API RasterizerDesc
            {

            };
            struct FXCC_API RenderStates 
            {
            public:

                VertexTypeDesc m_VertexDescs[(int)common::VertexType::_vertex_end_];

                IndexTypeDesc m_IndexDescs[(int)common::IndexType::_index_end_];

                ModeTypeDesc m_ModeDescs[(int)common::ModeType::_mode_end_];

                DataTypeDesc m_DataTypeDescs[(int)common::DataType::_count_];

                SamplerTypeDesc m_SamplerDescs[(int)common::SamplerType::_count_];

                FormatDesc m_FormatDescs[5];

                DepthStencilDesc m_DepthStencilDesc[(int)common::DepthStencilType::_END_];

                BlendDesc m_BlendDesc[(int)(common::BlendType::_END_)];

                RasterizerDesc m_RasterizerDesc[(int)(common::RasterizerType::_END_)];

            public:

                SamplerTypeDesc GetSamplerTypeDesc(const fxcc::graph::common::SamplerType& type);

                VertexTypeDesc GetVertexDesc(const common::VertexType& type);

                IndexTypeDesc GetIndexDesc(const common::IndexType type);

                ModeTypeDesc GetModeTypeDesc(const common::ModeType& type);

                SamplerDesc GetSamplerLinearClamp();

                bool InitVertexDesc();

                bool InitIndexDesc();
                
                bool InitModeDesc();
                
                bool InitSamplerDesc();

                bool InitFormatDesc();

                void SetSamplerState(const int startSlot, const int numSlot, const fxcc::graph::common::SamplerType& samplerType);

                void SetSamplerStates();

                const FormatDesc GetFormatDesc(const int channel);

                const DXGI_FORMAT GetFormat(const int numChannel, bool hdr);
          
            public:

                bool Init();

                ID3D11Device* Device();

                ID3D11DeviceContext* Context();

                ID3D11Device* m_Device{0};

                ID3D11DeviceContext* m_Context{0};

                static RenderStates& Inst();

            };
        }
    }
};